package com.mini.game.auth;

import com.mini.common.RedisService;
import com.mini.common.constant.CommonErrorCode;
import com.mini.common.constant.RedisConstant;
import com.mini.common.util.JacksonUtil;
import com.mini.common.vo.ResData;
import com.mini.game.ApplicationContextProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
 * @author 小鱼儿
 * @date 2020/11/18 12:44
 */
public class AuthorizationInterceptor implements HandlerInterceptor {
    private final static Logger logger = LoggerFactory.getLogger(AuthorizationInterceptor.class);
    //存放鉴权信息的Header名称，默认是Authorization
    private String httpHeaderName = "token";

    private RedisService redisService;

    public RedisService getRedisService() {
        if (redisService == null) {
            redisService = ApplicationContextProvider.getBean(RedisService.class);
        }
        return redisService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        logger.error("url={} ", request.getRequestURL().toString());
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
//        HandlerMethod handlerMethod = (HandlerMethod) handler;
        RedisService redisService = getRedisService();
        String token = request.getHeader(httpHeaderName);
        long userId = 0;
        int errorCode = CommonErrorCode.ERR_NOT_AUTH;
        if (!StringUtils.isEmpty(token)) {
            userId = redisService.getLong(RedisConstant.TOKEN_USER_ID + token);
        }
        if (userId > 0) {
            redisService.expire(RedisConstant.TOKEN_USER_ID + token, RedisConstant.TOKEN_EXPIRE_TIME);
            redisService.expire(RedisConstant.TOKEN + userId, RedisConstant.TOKEN_EXPIRE_TIME);
            redisService.expire(RedisConstant.TOKEN_SERVER_ID + token, RedisConstant.TOKEN_EXPIRE_TIME);
            ThreadLocalUserContext.bindUserId(userId);
            return true;
        } else {
            logger.error("token={} 过期了", token);
            PrintWriter out = null;
            try {
                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                out = response.getWriter();
                String ret = JacksonUtil.toJsonString(ResData.buildErrorResData(errorCode));
                out.println(ret);
                return false;
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            } finally {
                if (null != out) {
                    out.flush();
                    out.close();
                }
            }
            return false;
        }
}

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ThreadLocalUserContext.unbindUserId();
    }
}
